package Init

import (
	dlog "gin-gateway/core/log"
	"fmt"
	"os"
	"github.com/spf13/viper"
	"strings"
	"path/filepath"
	"bytes"
	"log"
	"time"
)

// 读取 base 文件的配置，unmarshal 到 BaseConf 结构体，并用它构造 log 配置、开启 log
func InitBaseConf(confPath string) error {
	BaseCfg = &BaseConf{}
	err := ParseConfig(confPath, BaseCfg)
	if err != nil {
		return err
	}

	if BaseCfg.DebugMode == "" {
		if BaseCfg.Base.DebugMode != "" {
			BaseCfg.DebugMode = BaseCfg.Base.DebugMode
		} else {
			BaseCfg.DebugMode = "debug"
		}
	}
	if BaseCfg.TimeLocation == "" {
		if BaseCfg.Base.TimeLocation != "" {
			BaseCfg.TimeLocation = BaseCfg.Base.TimeLocation
		} else {
			BaseCfg.TimeLocation = "Asia/Shanghai"
		}
	}
	if BaseCfg.Log.Level == "" {
		BaseCfg.Log.Level = "trace"
	}

	// 配置 log
	logConf := dlog.LogConf{
		Level:   BaseCfg.Log.Level,
		Tracing: BaseCfg.Log.Tracing,
		FW: dlog.ConfFileWriter{
			On:              BaseCfg.Log.FW.On,
			LogPath:         BaseCfg.Log.FW.LogPath,
			RotateLogPath:   BaseCfg.Log.FW.RotateLogPath,
			WfLogPath:       BaseCfg.Log.FW.WfLogPath,
			RotateWfLogPath: BaseCfg.Log.FW.RotateWfLogPath,
		},
		CW: dlog.ConfConsoleWriter{
			On:    BaseCfg.Log.CW.On,
			Color: BaseCfg.Log.CW.Color,
		},
	}
	if err := dlog.SetupDefaultLogWithConf(logConf); err != nil {
		panic(err)
	}
	dlog.SetLayout("2006-01-02T15:04:05.000")
	return nil
}

// InitRedisConf 读取 redis 文件的配置，unmarshal 到 ConfRedis 结构体
func InitRedisConf(path string) error {
	RedisConf := &RedisMapConf{}
	err := ParseConfig(path, RedisConf)
	if err != nil || RedisConf == nil {
		log.Fatalln("Redis config nil or err :", err)
		return err
	}
	RedisMapCfg = RedisConf
	return nil
}

// InitRedisConf 读取 redis 文件的配置，unmarshal 到 ConfRedis 结构体
func InitMysqlConf(path string) error {
	DbConf := &MysqlMapConf{}
	err := ParseConfig(path, DbConf)
	if err != nil || DbConf == nil {
		log.Fatalln("mysql config nil or err :", err)
		return err
	}
	MysqlMapCfg = DbConf
	return nil
}

func InitEtcdConf(path string) error {
	Etcdconf := &EtcdConf{}
	err := ParseConfig(path, Etcdconf)
	if err != nil {
		return err
	}
	if err != nil || Etcdconf == nil {
		log.Fatalln("Etcd config nil or err :", err)
		return err
	}
	EtcdCfg = Etcdconf
	return nil
}

// 解析配置目录下的所有配置文件，用配置文件名组成 ViperConfMap 结构
func InitViperConf() error {
	if ConfEnvPath == "" {
		return fmt.Errorf("配置目录路径为空")
	}
	dir, err := os.Open(ConfEnvPath)
	if err != nil {
		return fmt.Errorf("无法打开配置目录 %q: %w", ConfEnvPath, err)
	}
	defer dir.Close() // 确保目录被关闭

	DirEntry, err := dir.ReadDir(-1) // -1 表示读取所有条目
	if err != nil {
		return fmt.Errorf("读取配置目录内容失败: %w", err)
	}

	if ViperConfMap == nil {
		ViperConfMap = make(map[string]*viper.Viper)
	}

	// 处理每个文件
	for _, entry := range DirEntry {
		if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".toml") {
			continue
		}
		filePath := filepath.Join(ConfEnvPath, entry.Name())
		data, err := os.ReadFile(filePath)
		if err != nil {
			return fmt.Errorf("读取配置文件 %q 失败: %w", filePath, err)
		}

		v := viper.New()
		v.SetConfigType("toml")
		if err := v.ReadConfig(bytes.NewBuffer(data)); err != nil {
			return fmt.Errorf("解析配置文件 %q 失败: %w", filePath, err)
		}

		configName := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
		if configName == "" {
			log.Printf("警告: 无效的配置文件名 %q，跳过", entry.Name())
			continue
		}
		ViperConfMap[configName] = v
	}
	return nil
}

// GetStringConf 获取配置文件中各种类型的值
func GetStringConf(key string) string {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return ""
	}
	v, ok := ViperConfMap[keys[0]]
	if !ok {
		return ""
	}
	confString := v.GetString(strings.Join(keys[1:], "."))
	return confString
}

func GetStringMapConf(key string) map[string]interface{} {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return nil
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetStringMap(strings.Join(keys[1:], "."))
	return conf
}
func GetConf(key string) interface{} {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return nil
	}
	v := ViperConfMap[keys[0]]
	conf := v.Get(strings.Join(keys[1:], "."))
	return conf
}
func GetBoolConf(key string) bool {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return false
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetBool(strings.Join(keys[1:], "."))
	return conf
}
func GetFloat64Conf(key string) float64 {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return 0
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetFloat64(strings.Join(keys[1:], "."))
	return conf
}
func GetIntConf(key string) int {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return 0
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetInt(strings.Join(keys[1:], "."))
	return conf
}
func GetStringMapStringConf(key string) map[string]string {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return nil
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetStringMapString(strings.Join(keys[1:], "."))
	return conf
}
func GetStringSliceConf(key string) []string {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return nil
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetStringSlice(strings.Join(keys[1:], "."))
	return conf
}
func GetTimeConf(key string) time.Time {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return time.Now()
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetTime(strings.Join(keys[1:], "."))
	return conf
}
func GetDurationConf(key string) time.Duration {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return 0
	}
	v := ViperConfMap[keys[0]]
	conf := v.GetDuration(strings.Join(keys[1:], "."))
	return conf
}

// 是否设置了key，没用到
func IsSetConf(key string) bool {
	keys := strings.Split(key, ".")
	if len(keys) < 2 {
		return false
	}
	v := ViperConfMap[keys[0]]
	conf := v.IsSet(strings.Join(keys[1:], "."))
	return conf
}
